﻿using System;
using GeoAPI.Geometries;

namespace YJKGridTopologyCal.GeometriesGraph
{
	public class Depth
	{
		public static int DepthAtLocation(Location _location)
		{
			if (_location == Location.Exterior)
			{
				return 0;
			}
			if (_location == Location.Interior)
			{
				return 1;
			}
			return -1;
		}

		public Depth()
		{
			for (int i = 0; i < 2; i++)
			{
				for (int j = 0; j < 3; j++)
				{
					this.depth[i, j] = -1;
				}
			}
		}

		public int GetDepth(int geomIndex, Positions posIndex)
		{
			return this.depth[geomIndex, (int)posIndex];
		}

		public void SetDepth(int geomIndex, Positions posIndex, int depthValue)
		{
			this.depth[geomIndex, (int)posIndex] = depthValue;
		}

		public int this[int geomIndex, Positions posIndex]
		{
			get
			{
				return this.GetDepth(geomIndex, posIndex);
			}
			set
			{
				this.SetDepth(geomIndex, posIndex, value);
			}
		}

		public Location GetLocation(int geomIndex, Positions posIndex)
		{
			if (this.depth[geomIndex, (int)posIndex] <= 0)
			{
				return Location.Exterior;
			}
			return Location.Interior;
		}

		public void Add(int geomIndex, Positions posIndex, Location _location)
		{
			if (_location == Location.Interior)
			{
				this.depth[geomIndex, (int)posIndex]++;
			}
		}

		public bool IsNull()
		{
			for (int i = 0; i < 2; i++)
			{
				for (int j = 0; j < 3; j++)
				{
					if (this.depth[i, j] != -1)
					{
						return false;
					}
				}
			}
			return true;
		}

		public bool IsNull(int geomIndex)
		{
			return this.depth[geomIndex, 1] == -1;
		}

		public bool IsNull(int geomIndex, Positions posIndex)
		{
			return this.depth[geomIndex, (int)posIndex] == -1;
		}

		public void Add(Label lbl)
		{
			for (int i = 0; i < 2; i++)
			{
				for (int j = 1; j < 3; j++)
				{
					Location location = lbl.GetLocation(i, (Positions)j);
					if (location == Location.Exterior || location == Location.Interior)
					{
						if (this.IsNull(i, (Positions)j))
						{
							this.depth[i, j] = Depth.DepthAtLocation(location);
						}
						else
						{
							this.depth[i, j] += Depth.DepthAtLocation(location);
						}
					}
				}
			}
		}

		public int GetDelta(int geomIndex)
		{
			return this.depth[geomIndex, 2] - this.depth[geomIndex, 1];
		}

		public void Normalize()
		{
			for (int i = 0; i < 2; i++)
			{
				if (!this.IsNull(i))
				{
					int num = this.depth[i, 1];
					if (this.depth[i, 2] < num)
					{
						num = this.depth[i, 2];
					}
					if (num < 0)
					{
						num = 0;
					}
					for (int j = 1; j < 3; j++)
					{
						int num2 = 0;
						if (this.depth[i, j] > num)
						{
							num2 = 1;
						}
						this.depth[i, j] = num2;
					}
				}
			}
		}

		public override string ToString()
		{
			return string.Format("A: {0},{1} B: {2},{3}", new object[]
			{
				this.depth[0, 1],
				this.depth[0, 2],
				this.depth[1, 1],
				this.depth[1, 2]
			});
		}

		private const int @null = -1;

		private readonly int[,] depth = new int[2, 3];
	}
}
